(function (win) {
	win.plass = function () {
		if (!win.document.body.getAttribute("plass-id")) win.document.body.setAttribute("plass-id", win.document.body.id || "body");
		if (!win.document.body.getAttribute("plass-key")) win.document.body.setAttribute("plass-key", win.document.body.id || "body");

		return win.$(".plass").each(function () {
			var that = win.$(this);

			var plass = that.data("plass");
			if (!plass) {
				that.data("plass", (plass = []));

				var plassAttr = that.attr("plass");
				if (!plassAttr) throw "class plass need to attribute plass";

				var plassSplit = plassAttr.split(/s+/);
				win.plass.add(that, plassSplit);
			}
		});
	};

	win.plass.add = function (that, plass) {
		if (!$.isArray(plass)) throw "add plass to need a array parameter";

		var plassMap = that.data("plass-map");
		if (!plassMap) that.data("plass-map", (plassMap = {}));

		var plassOk = [];
		for (var i = 0; i < plass.length; i++) {
			var plassItem = plass[i];
			if (plassItem.length == 0) continue;
			if (plassMap[plassItem]) continue;
			plassOk.push(plassItem);
		};
		plass = plassOk;


		var plassClosest = that.closest("[plass-id],[id]");
		var plassId = plassClosest.attr("plass-id");
		var plassKey = plassClosest.attr("plass-key");
		if (!plassId) {
			plassClosest.attr("plass-id", (plassId = plassClosest.attr("id"))).attr("plass-key", (plassKey = plassId));
		}

		for (var i = 0; i < plass.length; i++) {
			var plassItem = plass[i];
			if (plassItem.length == 0) continue;

			var classArr = plassMap[plassItem];
			if (!classArr) classArr = plassMap[plassItem] = [];

			that.attr("plass-id", plassId);
			if (plassItem[0] == "-") {
				that.addClass(plassKey + plassItem);
				classArr.push(plassKey + plassItem);
				that.addClass(plassId + "-" + plassKey + plassItem);
				classArr.push(plassId + "-" + plassKey + plassItem);
				that.attr("plass-key", plassKey);
			} else {
				that.addClass(plassItem);
				classArr.push(plassItem);
				that.addClass(plassId + "-" + plassItem);
				classArr.push(plassId + "-" + plassItem);
				that.attr("plass-key", plassItem);
			}
		}

		var plassAttr = "";
		for (var plassItem in plassMap) {
			if (plassAttr.length > 0) plassAttr += " ";
			plassAttr += plassItem;
		};
		that.attr("plass", plassAttr);

		that.removeClass("plass");
	};

	win.plass.remove = function (that, plass) {
		if (!$.isArray(plass)) throw "remove plass to need a array parameter";

		var plassMap = that.data("plass-map");
		if (!plassMap) that.data("plass-map", (plassMap = {}));

		for (var i = 0; i < plass.length; i++) {
			var plassItem = plass[i];
			if (plassItem.length == 0) continue;
			if (!plassMap[plassItem]) continue;

			var classArr = plassMap[plassItem];
			if (classArr) {
				for (var i = 0; i < classArr.length; i++) that.removeClass(classArr[i]);

				delete plassMap[plassItem];
			}
		};

		var plassAttr = "";
		for (var plassItem in plassMap) {
			if (plassAttr.length > 0) plassAttr += " ";
			plassAttr += plassItem;
		};
		that.attr("plass", plassAttr);
	};

	win.$.fn.addPlass = function (plass) {
		return this.each(function () {
			win.plass.add(win.$(this), plass);
		});
	};

	win.$.fn.removePlass = function (plass) {
		return this.each(function () {
			win.plass.remove(win.$(this), plass);
		});
	};
})(window)